package com.hutiao.snowhb.common;

import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.google.gson.Gson;
import com.hutiao.snowhb.entities.PhotographerBean;
import com.hutiao.snowhb.entities.SnowMMLocation;
import com.hutiao.snowhb.entities.UserLocation;
import com.hutiao.snowhb.entities.WeixinAccessToken;
import com.hutiao.snowhb.wechat.vo.WxRecvEventGeo;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;
import com.mongodb.MongoException;
import com.mongodb.MongoOptions;
import com.mongodb.util.JSON;

public class MongoUtil {
	
	private static Logger logger = Logger.getLogger(MongoUtil.class);

	private static MongoClient client;
	
	/**
     * 根据名称获取DB，相当于是连接
     * 
     * @param dbName
     * @return
     */
    public static DB getDB(String dbName) {
        if (client == null) {
            // 初始化
            init();
        }
        return client.getDB(dbName);
    }
    
    /**
     * 初始化连接池，设置参数。
     */
    private static void init() {
    	
//    	connectionsPerHost：每个主机的连接数
//    	threadsAllowedToBlockForConnectionMultiplier：线程队列数，它以上面connectionsPerHost值相乘的结果就是线程队列最大值。如果连接线程排满了队列就会抛出“Out of semaphores to get db”错误。
//    	maxWaitTime:最大等待连接的线程阻塞时间
//    	connectTimeout：连接超时的毫秒。0是默认和无限
//    	socketTimeout：socket超时。0是默认和无限
//    	autoConnectRetry：这个控制是否在一个连接时，系统会自动重试

        String host = "59.175.238.115";// 主机名
        int port = 27017;// 端口
        int poolSize = 20;// 连接数量
        int blockSize = 10; // 等待队列长度
        // 其他参数根据实际情况进行添加
        try {
        	client = new MongoClient(host, port);
            MongoOptions opt = client.getMongoOptions();
            opt.connectionsPerHost = poolSize;
            opt.threadsAllowedToBlockForConnectionMultiplier = blockSize;
        } catch (UnknownHostException e) {
            // log error
        	logger.error("UnknownHostException", e);
        } catch (MongoException e) {
            // log error
        	logger.error("MongoException", e);
        }
    }
    
    
    public static void save(Map<String, Object> data, String dbName, String collectionName) throws Exception {
		if (data != null) {
			DB db = MongoUtil.getDB("dbName");
			DBCollection coll = db.getCollection(collectionName);
			data.put("createTime", new Date());
			BasicDBObject content = new BasicDBObject(data);
			
			coll.save(content);
		}
	}
    
    
    
    
    public static void saveNearbyMMSession(String openId) throws Exception {
    	
    	DB db = MongoUtil.getDB("snowmm");
		DBCollection coll = db.getCollection("nearby_session");
    	
		DBObject session = new BasicDBObject();
		session.put("openId", openId);
		session.put("time", DateTimeUtil.currentTimeStr());
		
		coll.save(session);
    }
    
    public static String findNearbyMMSession(String openId) {
    	
    	DB db = MongoUtil.getDB("snowmm");
		DBCollection coll = db.getCollection("nearby_session");
		DBObject session = coll.findOne(new BasicDBObject("openId", openId));
		
		if (session == null) {
			return null;
		}
		
		Date time = DateTimeUtil.String2Date2(session.get("time").toString());
		if (DateTimeUtil.getTimeDifference(new Date(), time) > 10) {
			coll.remove(session);
			return null;
		}
		
		return session.get("openId")==null ? null : session.get("openId").toString();
    }
    
    public static void removeNearbyMMSession(String openId) {
    	DB db = MongoUtil.getDB("snowmm");
		DBCollection coll = db.getCollection("nearby_session");
		coll.remove(new BasicDBObject("openId", openId));
    }
    
    
    
    public static void saveMMCheckinSession(SnowMMLocation loca) throws Exception {
    	
    	if (loca != null) {
    		DB db = MongoUtil.getDB("snowmm");
			DBCollection coll = db.getCollection("checkin_session");
			
			DBObject session = new BasicDBObject();
			session.put("mmid", loca.getMmid());
			session.put("time", DateTimeUtil.currentTimeStr());
			session.put("latitude", loca.getLatitude());
			session.put("longitude", loca.getLongitude());
			session.put("label", loca.getLabel());
			session.put("poi", loca.getPoi());
			
			coll.save(session);
    	}
    	
    }
    
    public static SnowMMLocation findMMCheckinSession(int mmid) {
    	
    	DB db = MongoUtil.getDB("snowmm");
		DBCollection coll = db.getCollection("checkin_session");
		DBObject session = coll.findOne(new BasicDBObject("mmid", mmid));
		
		if (session == null) {
			return null;
		}
		
		Date time = DateTimeUtil.String2Date2(session.get("time").toString());
		if (DateTimeUtil.getTimeDifference(new Date(), time) > 10) {
			coll.remove(session);
			return null;
		}
		
		if (session.get("latitude") == null || session.get("latitude") == null) {
			coll.remove(session);
			return null;
		}
		
		SnowMMLocation loca = new SnowMMLocation();
		loca.setMmid(mmid);
		loca.setLatitude(Double.parseDouble(session.get("latitude").toString()));
		loca.setLongitude(Double.parseDouble(session.get("longitude").toString()));
		loca.setLabel(session.get("label")==null ? null : session.get("label").toString());
		loca.setPoi(session.get("poi")==null ? null : session.get("poi").toString());
		
		return loca;
    }
    
    
    public static void removeMMCheckinSession(int mmid) {
    	DB db = MongoUtil.getDB("snowmm");
		DBCollection coll = db.getCollection("checkin_session");
		coll.remove(new BasicDBObject("mmid", mmid));
    }
    
    
    public static void saveSession(PhotographerBean bean) throws Exception {
    	
    	if (bean != null) {
    		DB db = MongoUtil.getDB("huodong");
			DBCollection coll = db.getCollection("photo_session");
			
			DBObject session = new BasicDBObject();
			session.put("key", "photographer_"+bean.getOpenId());
			session.put("time", new Date());
			session.put("openid", bean.getOpenId());
			session.put("photo_url", bean.getPhotoUrl());
			session.put("media_id", bean.getMediaId());
			session.put("photo_title", bean.getPhotoTitle());
			session.put("photo_desc", bean.getPhotoDesc());
			
			coll.save(session);
			
			//查看是否添加成功
//	        DBCursor cur = coll.find();
//	        while (cur.hasNext()) {
//	            System.out.println(cur.next());
//	        }
    	}
    	
    }
    
    public static PhotographerBean findSession(String key) {
    	DB db = MongoUtil.getDB("huodong");
		DBCollection coll = db.getCollection("photo_session");
		DBObject session = coll.findOne(new BasicDBObject("key", key));
		
		PhotographerBean bean = new PhotographerBean();
		if (session != null) {
			bean.setOpenId(session.get("openid")==null ? null : session.get("openid").toString());
			bean.setPhotoUrl(session.get("photo_url")==null ? null : session.get("photo_url").toString());
			bean.setMediaId(session.get("media_id")==null ? null : session.get("media_id").toString());
			bean.setPhotoTitle(session.get("photo_title")==null ? null : session.get("photo_title").toString());
			bean.setPhotoDesc(session.get("photo_desc")==null ? null : session.get("photo_desc").toString());
		}
		
		return bean;
    }
    
    
    public static void removeSession(String key) {
    	
    	DB db = MongoUtil.getDB("huodong");
		DBCollection coll = db.getCollection("photo_session");
		coll.remove(new BasicDBObject("key", key));
    }
    
    
    
    public static void saveUserLocal(WxRecvEventGeo geo) throws Exception {
    	
    	if (geo != null) {
    		DB db = MongoUtil.getDB("snowmm");
			DBCollection coll = db.getCollection("user_last_location");
			
			DBObject session = new BasicDBObject();
			session.put("key", "user_"+geo.getFromUser());
			session.put("time", new Date());
			session.put("openid", geo.getFromUser());
			session.put("latitude", geo.getLatitude());
			session.put("longitude", geo.getLongitude());
			session.put("precision", geo.getPrecision());
			
			coll.save(session);
			
			//查看是否添加成功
//	        DBCursor cur = coll.find();
//	        while (cur.hasNext()) {
//	            System.out.println(cur.next());
//	        }
    	}
    	
    }
    
    public static UserLocation findUserLocal(String openId) {
    	
    	String key = "user_"+openId;
    	
    	DB db = MongoUtil.getDB("snowmm");
		DBCollection coll = db.getCollection("user_last_location");
		DBObject session = coll.findOne(new BasicDBObject("key", key));
		
		UserLocation geo = new UserLocation();
		if (session != null) {
			geo.setOpenId(session.get("openid")==null ? null : session.get("openid").toString());
			geo.setLatitude(session.get("latitude")==null ? null : Double.parseDouble(session.get("latitude").toString()));
			geo.setLongitude(session.get("longitude")==null ? null : Double.parseDouble(session.get("longitude").toString()));
			geo.setPrecision(session.get("precision")==null ? null : Double.parseDouble(session.get("precision").toString()));
		}
		
		return geo;
    }
    
    public static void removeUserLocal(String openId) {
    	
    	String key = "user_"+openId;
    	
    	DB db = MongoUtil.getDB("snowmm");
		DBCollection coll = db.getCollection("user_last_location");
		coll.remove(new BasicDBObject("key", key));
    }
    
    
    public static void main(String[] args) throws Exception {
    	
    	//MongoUtil mongo = new MongoUtil();
    	
//    	DB db = MongoUtil.getDB("test");
//    	DBCollection coll = db.getCollection("users");
//    	
//    	DBObject user1 = new BasicDBObject("name","张三");
//        DBObject user2 = new BasicDBObject("age",20);
//        List<DBObject> list = new ArrayList<DBObject>();  
//        list.add(user1);
//        list.add(user2);
//        coll.insert(list);
//        //查看是否添加成功
//        DBCursor cur = coll.find();
//        while (cur.hasNext()) {
//            System.out.println(cur.next());
//        }
    	

    	
//    	PhotographerBean bean = new PhotographerBean();
//    	bean.setOpenId("openid");
//    	bean.setId(99);
//    	bean.setCreateTime(new Date());
//    	
//    	MongoUtil.saveSession(bean);
    	
//    	PhotographerBean bean = MongoUtil.findSession("photographer_openid");
//    	
//    	System.out.println(bean.getOpenId());
    	
    	
    	
    }
}
